package com.atguigu.juc.atomics;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 题目：实现一个自旋锁 自旋锁好处：循环比较获取没有类似wait的阻塞。 通过CAS操作完成自旋锁，A线程先进来调用myLock方法自己持有锁5秒钟，B随后进来后发现
 * 当前有线程持有锁，不是null，所以只能通过自旋等待，直到A释放锁后B随后抢到。
 *
 * @author yfstart
 * @create 2022-07-20 14:13
 */
public class SpinLockDemo {
  AtomicReference<Thread> atomicReference = new AtomicReference<>();

  public void lock() {
    Thread thread = Thread.currentThread();
    System.out.println(Thread.currentThread().getName() + "\t ---come in");
    while (!atomicReference.compareAndSet(null, thread)) {}
  }

  public void unlock() {
    Thread thread = Thread.currentThread();
    atomicReference.compareAndSet(thread, null);
    System.out.println(Thread.currentThread().getName() + "\t ---task over,unlock");
  }

  public static void main(String[] args) {
    SpinLockDemo spinLockDemo = new SpinLockDemo();

    new Thread(()->{
      spinLockDemo.lock();
      // 持有锁5秒钟
      try { TimeUnit.MILLISECONDS.sleep(5000); } catch (InterruptedException e) { e.printStackTrace();}
      spinLockDemo.unlock();
    },"A").start();

    // 暂停500毫秒，线程A先于B之前启动
    try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace();}

    new Thread(()->{
      spinLockDemo.lock();
      spinLockDemo.unlock();
    },"B").start();
  }
}
